"""定时任务模块"""

import asyncio
from datetime import datetime, time
from typing import List
from nonebot import get_bot, logger, require
from nonebot.adapters.onebot.v11 import Bot
from sqlalchemy import and_, func, desc
from sqlalchemy.orm import Session

require("nonebot_plugin_apscheduler")
from nonebot_plugin_apscheduler import scheduler

from .database import get_db_session, MessageRecord, ResetState, init_db
from .config import config
from .utils import format_ranking_text, get_emoji_for_rank


@scheduler.scheduled_job(
    "cron",
    hour=config.message_counter_auto_push_time.hour,
    minute=config.message_counter_auto_push_time.minute,
    id="auto_push_ranking"
)
async def auto_push_ranking():
    """自动推送排行榜"""
    if not config.message_counter_auto_push_enable:
        return
    
    try:
        bot = get_bot()
        init_db()
        
        with get_db_session() as session:
            # 获取所有有数据的群组
            groups = session.query(MessageRecord.group_id, MessageRecord.group_name).filter(
                MessageRecord.today_count > 0
            ).distinct().all()
            
            for group_id, group_name in groups:
                # 检查群组是否在推送列表中
                if config.message_counter_auto_push_groups:
                    if group_id not in config.message_counter_auto_push_groups:
                        continue
                
                # 获取今日排行榜
                records = session.query(MessageRecord).filter(
                    and_(
                        MessageRecord.group_id == group_id,
                        MessageRecord.today_count > 0
                    )
                ).order_by(desc(MessageRecord.today_count)).limit(
                    config.message_counter_auto_push_limit
                ).all()
                
                if not records:
                    continue
                
                # 格式化排行榜消息
                message = format_auto_push_ranking(records, group_name or group_id)
                
                # 发送消息
                try:
                    await bot.send_group_msg(group_id=int(group_id), message=message)
                    logger.info(f"自动推送排行榜到群 {group_id} 成功")
                    
                    # 添加延迟避免发送过快
                    await asyncio.sleep(1)
                    
                except Exception as e:
                    logger.error(f"自动推送排行榜到群 {group_id} 失败: {e}")
                    
    except Exception as e:
        logger.error(f"自动推送排行榜任务失败: {e}")


@scheduler.scheduled_job(
    "cron",
    hour=0,
    minute=0,
    id="daily_reset"
)
async def daily_reset():
    """每日数据重置"""
    try:
        init_db()
        
        with get_db_session() as session:
            # 更新所有记录的昨日数据
            records = session.query(MessageRecord).all()
            
            for record in records:
                record.yesterday_count = record.today_count
                record.today_count = 0
            
            session.commit()
            
            # 记录重置状态
            reset_state = ResetState(
                reset_type="daily",
                reset_time=datetime.now(),
                affected_records=len(records)
            )
            session.add(reset_state)
            session.commit()
            
            logger.info(f"每日数据重置完成，影响 {len(records)} 条记录")
            
    except Exception as e:
        logger.error(f"每日数据重置失败: {e}")


@scheduler.scheduled_job(
    "cron",
    day_of_week="mon",
    hour=0,
    minute=5,
    id="weekly_reset"
)
async def weekly_reset():
    """每周数据重置"""
    try:
        init_db()
        
        with get_db_session() as session:
            # 重置所有记录的周数据
            records = session.query(MessageRecord).all()
            
            for record in records:
                record.week_count = 0
            
            session.commit()
            
            # 记录重置状态
            reset_state = ResetState(
                reset_type="weekly",
                reset_time=datetime.now(),
                affected_records=len(records)
            )
            session.add(reset_state)
            session.commit()
            
            logger.info(f"每周数据重置完成，影响 {len(records)} 条记录")
            
    except Exception as e:
        logger.error(f"每周数据重置失败: {e}")


@scheduler.scheduled_job(
    "cron",
    day=1,
    hour=0,
    minute=10,
    id="monthly_reset"
)
async def monthly_reset():
    """每月数据重置"""
    try:
        init_db()
        
        with get_db_session() as session:
            # 重置所有记录的月数据
            records = session.query(MessageRecord).all()
            
            for record in records:
                record.month_count = 0
            
            session.commit()
            
            # 记录重置状态
            reset_state = ResetState(
                reset_type="monthly",
                reset_time=datetime.now(),
                affected_records=len(records)
            )
            session.add(reset_state)
            session.commit()
            
            logger.info(f"每月数据重置完成，影响 {len(records)} 条记录")
            
    except Exception as e:
        logger.error(f"每月数据重置失败: {e}")


@scheduler.scheduled_job(
    "cron",
    month=1,
    day=1,
    hour=0,
    minute=15,
    id="yearly_reset"
)
async def yearly_reset():
    """每年数据重置"""
    try:
        init_db()
        
        with get_db_session() as session:
            # 重置所有记录的年数据
            records = session.query(MessageRecord).all()
            
            for record in records:
                record.year_count = 0
            
            session.commit()
            
            # 记录重置状态
            reset_state = ResetState(
                reset_type="yearly",
                reset_time=datetime.now(),
                affected_records=len(records)
            )
            session.add(reset_state)
            session.commit()
            
            logger.info(f"每年数据重置完成，影响 {len(records)} 条记录")
            
    except Exception as e:
        logger.error(f"每年数据重置失败: {e}")


@scheduler.scheduled_job(
    "cron",
    hour=config.message_counter_dragon_king_check_time.hour,
    minute=config.message_counter_dragon_king_check_time.minute,
    id="dragon_king_check"
)
async def dragon_king_check():
    """龙王检查和禁言"""
    if not config.message_counter_dragon_king_enable:
        return
    
    try:
        bot = get_bot()
        init_db()
        
        with get_db_session() as session:
            # 获取所有群组的今日发言冠军
            groups = session.query(MessageRecord.group_id).filter(
                MessageRecord.today_count > 0
            ).distinct().all()
            
            for (group_id,) in groups:
                # 检查群组是否启用龙王功能
                if config.message_counter_dragon_king_groups:
                    if group_id not in config.message_counter_dragon_king_groups:
                        continue
                
                # 获取今日发言最多的用户
                top_user = session.query(MessageRecord).filter(
                    and_(
                        MessageRecord.group_id == group_id,
                        MessageRecord.today_count > 0
                    )
                ).order_by(desc(MessageRecord.today_count)).first()
                
                if not top_user:
                    continue
                
                # 检查是否达到龙王条件
                if top_user.today_count >= config.message_counter_dragon_king_threshold:
                    try:
                        # 禁言龙王
                        await bot.set_group_ban(
                            group_id=int(group_id),
                            user_id=int(top_user.user_id),
                            duration=config.message_counter_dragon_king_duration
                        )
                        
                        # 发送龙王通知
                        username = top_user.username or top_user.user_id
                        message = f"🐉 恭喜 {username} 成为今日龙王！\n" \
                                f"今日发言: {top_user.today_count} 条\n" \
                                f"龙王禁言时间: {config.message_counter_dragon_king_duration // 60} 分钟"
                        
                        await bot.send_group_msg(group_id=int(group_id), message=message)
                        
                        logger.info(f"群 {group_id} 龙王 {top_user.user_id} 已被禁言")
                        
                    except Exception as e:
                        logger.error(f"龙王禁言失败 群:{group_id} 用户:{top_user.user_id} 错误:{e}")
                
    except Exception as e:
        logger.error(f"龙王检查任务失败: {e}")


@scheduler.scheduled_job(
    "cron",
    hour=2,
    minute=0,
    id="cleanup_old_data"
)
async def cleanup_old_data():
    """清理旧数据"""
    if not config.message_counter_cleanup_enable:
        return
    
    try:
        init_db()
        
        with get_db_session() as session:
            # 删除超过保留期限的重置记录
            cutoff_date = datetime.now() - config.message_counter_cleanup_days
            
            deleted_count = session.query(ResetState).filter(
                ResetState.reset_time < cutoff_date
            ).delete()
            
            session.commit()
            
            if deleted_count > 0:
                logger.info(f"清理旧数据完成，删除 {deleted_count} 条重置记录")
            
    except Exception as e:
        logger.error(f"清理旧数据失败: {e}")


def format_auto_push_ranking(records: List[MessageRecord], group_name: str) -> str:
    """格式化自动推送的排行榜消息"""
    result = f"🏆 {group_name} 今日发言排行榜\n\n"
    
    total_messages = sum(record.today_count for record in records)
    
    for i, record in enumerate(records, 1):
        username = record.username or record.user_id
        count = record.today_count
        emoji = get_emoji_for_rank(i)
        
        if config.message_counter_show_percentage and total_messages > 0:
            percentage = (count / total_messages) * 100
            result += f"{emoji} {i}. {username}: {count} 条 ({percentage:.1f}%)\n"
        else:
            result += f"{emoji} {i}. {username}: {count} 条\n"
    
    if config.message_counter_show_time:
        result += f"\n📅 {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
    
    return result.strip()


def start_scheduler():
    """启动定时任务"""
    logger.info("消息计数器定时任务已启动")
    
    # 根据配置启用/禁用任务
    if not config.message_counter_auto_push_enable:
        try:
            scheduler.remove_job("auto_push_ranking")
        except:
            pass
    
    if not config.message_counter_dragon_king_enable:
        try:
            scheduler.remove_job("dragon_king_check")
        except:
            pass
    
    if not config.message_counter_cleanup_enable:
        try:
            scheduler.remove_job("cleanup_old_data")
        except:
            pass


def stop_scheduler():
    """停止定时任务"""
    try:
        scheduler.remove_job("auto_push_ranking")
        scheduler.remove_job("daily_reset")
        scheduler.remove_job("weekly_reset")
        scheduler.remove_job("monthly_reset")
        scheduler.remove_job("yearly_reset")
        scheduler.remove_job("dragon_king_check")
        scheduler.remove_job("cleanup_old_data")
        logger.info("消息计数器定时任务已停止")
    except Exception as e:
        logger.error(f"停止定时任务失败: {e}")


# 在插件加载时启动定时任务
start_scheduler()